//
//  ViewController.m
//  FilterEffect
//
//  Created by YannisChou on 16/3/27.
//  Copyright © 2016年 Alibaba. All rights reserved.
//
//  实现滤镜效果
//  CIContext：图像上下文，用于管理整个图片处理过程，不同的图形上下文将利用不同的图像处理硬件进行图像处理
// （在iOS中可以通过不同的方式创建图像上下文，例如可以创建基于CPU的图像上下方、创建基于GPU的图像上下方以及创建OpenGL优化过的图像上下文）。
//  CIFilter：图像处理滤镜，每种滤镜有不同的参数设置。
//  CIImage：Core Image框架中的图像类型，主要用于输入和输出图像
//
//  使用滤镜的步骤
//  1.创建图像上下文CIContext
//  2.创建滤镜CIFilter
//  3.创建过滤原图片CIImage
//  4.调用CIFilter的setValue： forKey：方法为滤镜指定源图片
//  5.设置滤镜参数【可选】
//  6.取得输出图片显示或保存
//

#import "ViewController.h"
#define CONSTROLPANEL_FONTSIZE 12

@interface ViewController ()<UINavigationControllerDelegate,UIImagePickerControllerDelegate>{
    UIImagePickerController *_imagePickerController;// 系统照片选择控制器
    UIImageView *_imageView;// 图片显示控件
    CIContext *_context;// Core Image上下文
    CIImage *_image;// 我们要编辑的图像
    CIImage *_outputImage;// 处理后的图像
    CIFilter *_colorControlsFilter;// 色彩滤镜
}

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    
    [self initLayout];
}

#pragma mark 初始化布局
-(void)initLayout{
    // 初始化图片选择器
    _imagePickerController = [[UIImagePickerController alloc] init];
    _imagePickerController.delegate = self;
    
    // 创建图片显示控件
    _imageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 64, 320, 502)];
    _imageView.contentMode = UIViewContentModeScaleAspectFit;
    [self.view addSubview:_imageView];
    
    // 上方导航按钮
    self.navigationItem.title = @"Enhance";
    self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"Open" style:UIBarButtonItemStyleDone target:self action:@selector(openPhoto:)];
    self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"Save" style:UIBarButtonItemStyleDone target:self action:@selector(savePhoto:)];
    
    // 下放控制面板
    UIView *controlView = [[UIView alloc] initWithFrame:CGRectMake(0, 450, 320, 118)];
    // contentView.alpha = 0.2;
    // contentView.backgroundColor = [UIColor colorWithRed:46.0/255.0 green:178.0/255.0 blue:235.0/255.0 alpha:1];
    [self.view addSubview:controlView];
    // 饱和度(默认为1，大于饱和度增加小于1则降低)
    UILabel *lbSaturation = [[UILabel alloc] initWithFrame:CGRectMake(10, 10, 60, 25)];
    lbSaturation.text = @"Saturation";
    lbSaturation.font = [UIFont systemFontOfSize:CONSTROLPANEL_FONTSIZE];
    [controlView addSubview:lbSaturation];
    UISlider *slbSaturation = [[UISlider alloc] initWithFrame:CGRectMake(80, 10, 230, 30)];//注意UISlider高度虽然无法调整，很多朋友会说高度设置位0即可，事实上在iOS7中设置为0后是无法拖动的
    [controlView addSubview:slbSaturation];
    slbSaturation.minimumValue = 0;
    slbSaturation.maximumValue = 2;
    slbSaturation.value = 1;
    [slbSaturation addTarget:self action:@selector(changeSaturation:) forControlEvents:UIControlEventValueChanged];
    // 亮度(默认为0)
    UILabel *lbBrightness = [[UILabel alloc] initWithFrame:CGRectMake(10, 40, 60, 25)];
    lbBrightness.text = @"Brightness";
    lbBrightness.font = [UIFont systemFontOfSize:CONSTROLPANEL_FONTSIZE];
    [controlView addSubview:lbBrightness];
    UISlider *slbBrightness = [[UISlider alloc] initWithFrame:CGRectMake(80, 40, 230, 30)];
    [controlView addSubview:slbBrightness];
    slbBrightness.minimumValue = -1;
    slbBrightness.maximumValue = 1;
    slbBrightness.value = 0;
    [slbBrightness addTarget:self action:@selector(changeBrightness:) forControlEvents:UIControlEventValueChanged];
    // 对比度(默认为1)
    UILabel *lbContrast = [[UILabel alloc] initWithFrame:CGRectMake(10, 70, 60, 25)];
    lbContrast.text = @"Contrast";
    lbContrast.font = [UIFont systemFontOfSize:CONSTROLPANEL_FONTSIZE];
    [controlView addSubview:lbContrast];
    UISlider *slbContrast = [[UISlider alloc] initWithFrame:CGRectMake(80, 70, 230, 30)];
    [controlView addSubview:slbContrast];
    slbContrast.minimumValue = 0;
    slbContrast.maximumValue = 2;
    slbContrast.value = 1;
    [slbContrast addTarget:self action:@selector(changeContrast:) forControlEvents:UIControlEventValueChanged];
    
    // 初始化CIContext
    // 创建基于CPU的图像上下文
    // NSNumber *number=[NSNumber numberWithBool:YES];
    // NSDictionary *option=[NSDictionary dictionaryWithObject:number forKey:kCIContextUseSoftwareRenderer];
    // _context=[CIContext contextWithOptions:option];
    _context=[CIContext contextWithOptions:nil];//使用GPU渲染，推荐,但注意GPU的CIContext无法跨应用访问，例如直接在UIImagePickerController的完成方法中调用上下文处理就会自动降级为CPU渲染，所以推荐现在完成方法中保存图像，然后在主程序中调用
    // EAGLContext *eaglContext=[[EAGLContext alloc]initWithAPI:kEAGLRenderingAPIOpenGLES1];
    // _context=[CIContext contextWithEAGLContext:eaglContext];//OpenGL优化过的图像上下文
    
    // 取得滤镜
    _colorControlsFilter = [CIFilter filterWithName:@"CIColorControls"];
}

#pragma mark 打开图片选择器
-(void)openPhoto:(UIBarButtonItem *)btn{
    // 打开图片选择器
    [self presentViewController:_imagePickerController animated:YES completion:nil];
}

#pragma mark 保存图片选择器
-(void)savePhoto:(UIBarButtonItem *)btn{
    // 保存图片到相册
    UIImageWriteToSavedPhotosAlbum(_imageView.image, nil, nil, nil);
    UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"System Info" message:@"Save Success!" delegate:nil cancelButtonTitle:nil otherButtonTitles:@"OK", nil];
    [alert show];
}

#pragma mark 图片选器选择图片代理方法
-(void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary<NSString *,id> *)info{
    // 关闭图片选择器
    [self dismissViewControllerAnimated:YES completion:nil];
    // 取得选择图片
    UIImage *selectedImage = [info objectForKey:UIImagePickerControllerOriginalImage];
    _imageView.image = selectedImage;
    // 初始化CIImage源图像
    _image = [CIImage imageWithCGImage:selectedImage.CGImage];
    [_colorControlsFilter setValue:_image forKey:@"inputImage"];// 设置滤镜的输入图片
}

#pragma mark 将输出图片设置到UIImageView
-(void)setImage{
    CIImage *outputImage = [_colorControlsFilter outputImage];// 取得输出图像
    CGImageRef temp = [_context createCGImage:outputImage fromRect:[outputImage extent]];
    _imageView.image = [UIImage imageWithCGImage:temp]; // 转换为CGImage显示在界面中
    
    CGImageRelease(temp);// 释放CGImage对象
}

#pragma mark 调整饱和度
-(void)changeSaturation:(UISlider *)slider{
    [_colorControlsFilter setValue:[NSNumber numberWithFloat:slider.value] forKey:@"inputSaturation"];//设置滤镜参数
    [self setImage];
}

#pragma mark 调整亮度
-(void)changeBrightness:(UISlider *)slider{
    [_colorControlsFilter setValue:[NSNumber numberWithFloat:slider.value] forKey:@"inputBrightness"];
    [self setImage];
}

#pragma mark 调整对比度
-(void)changeContrast:(UISlider *)slider{
    [_colorControlsFilter setValue:[NSNumber numberWithFloat:slider.value] forKey:@"inputContrast"];
    [self setImage];
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

@end
